<!--
 @description:数据库树
 @author: mfish
 @date: 2023/3/31 21:29
-->
<template>
  <div>
    <BasicTree
      class="mr-0 overflow-hidden bg-white"
      title="数据库列表"
      toolbar
      search
      ref="asyncTreeRef"
      treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
      :treeData="treeData"
      :load-data="getTables"
      v-model:selectedKeys="selectedKeys"
      @select="handleSelect"
      @update:searchValue="handleSearch"
      :beforeRightClick="getRightMenuList"
    >
      <template #headerTools>
        <Tooltip title="新增数据库" v-if="hasPermission('sys:database:insert')">
          <Button type="text" size="small" @click="DBCreate">
            <template #icon>
              <Icon icon="ion:add-outline" />
            </template>
          </Button>
        </Tooltip>
      </template>
    </BasicTree>
    <DbConnectModal @register="registerModal" @success="handleSuccess" />
  </div>
</template>
<script lang="ts">
  import { BasicTree, ContextMenuItem, TreeActionType, TreeItem } from "/@/components/general/Tree";
  import { onMounted, ref, unref, computed, createVNode } from "vue";
  import { deleteDbConnect, getDbConnectList, getTableList } from "/@/api/sys/DbConnect";
  import { PageResult } from "/@/api/model/BaseModel";
  import { TableInfo } from "/@/api/sys/model/DbConnectModel";
  import { useAppStore } from "/@/store/modules/App";
  import Icon from "/@/components/general/Icon/src/Icon.vue";
  import { Button, Tooltip, Modal } from "ant-design-vue";
  import { usePermission } from "/@/hooks/web/UsePermission";
  import DbConnectModal from "/@/views/sys/db-connect/DbConnectModal.vue";
  import { useModal } from "/@/components/general/Modal";

  export default {
    name: "DBTree",
    components: { DbConnectModal, Icon, Tooltip, Button, BasicTree, Modal },
    emits: ["select", "search"],
    setup(_, { emit }) {
      const { hasPermission } = usePermission();
      const treeData = ref<TreeItem[]>([]);
      const asyncTreeRef = ref<Nullable<TreeActionType>>(null);
      let selectedKeys = ref<TreeItem[]>([]);
      const [registerModal, { openModal }] = useModal();
      const appStore = useAppStore();
      const color = computed(() => appStore.getProjectConfig.themeColor);

      async function fetch() {
        const dbList = (await getDbConnectList()).list;
        dbList.forEach((db) => {
          db["title"] = db.dbTitle;
          db["key"] = db.id;
          db["icon"] = "simple-icons:" + (db.dbType === 1 ? "postgresql" : db.dbType === 2 ? "oracle" : "mysql");
          db["iconColor"] = color;
        });
        treeData.value = dbList as unknown as TreeItem[];
        if (dbList?.length > 0) {
          let id = treeData.value[0].id;
          selectedKeys.value = [id];
          emit("select", treeData.value[0]);
        }
      }

      const showDeleteConfirm = (node) => {
        Modal.confirm({
          title: "确认删除提醒",
          content: createVNode("div", { style: "color:red;" }, "是否确认删除数据库"),
          onOk() {
            DBDelete(node);
          },
          class: "test"
        });
      };

      function getRightMenuList(node: any): ContextMenuItem[] {
        setSelect(node.key);
        if (!node.dbName) {
          return [];
        }
        const menus: ContextMenuItem[] = [];
        if (hasPermission("sys:database:update")) {
          menus.push({
            label: "修改",
            handler: () => {
              DBEdit(node);
            },
            icon: "ant-design:edit-outlined"
          });
        }
        if (hasPermission("sys:database:delete")) {
          menus.push({
            label: "删除",
            handler: () => {
              showDeleteConfirm(node);
            },
            icon: "ant-design:delete-outlined"
          });
        }
        return menus;
      }

      function handleSelect(_, e) {
        emit("select", e.node.dataRef, e.node?.parent?.node);
      }

      function setSelect(key) {
        if (key) {
          selectedKeys.value = [key];
          const keys = key.split(",");
          if (keys && keys.length === 2) {
            asyncTreeRef.value?.setExpandedKeys([keys[0]]);
            emit("select", asyncTreeRef.value?.getSelectedNode(key), asyncTreeRef.value?.getSelectedNode(keys[0]));
            return;
          }
          emit("select", asyncTreeRef.value?.getSelectedNode(key));
        }
      }

      function handleSearch(search, value) {
        emit("search", search, value);
      }

      async function getTables(treeNode) {
        if (treeNode.children) {
          return;
        }
        await buildTableTree(treeNode.eventKey);
      }

      function DBCreate() {
        openModal(true, {
          isUpdate: false
        });
      }

      function DBEdit(record: Recordable) {
        openModal(true, {
          record,
          isUpdate: true
        });
      }

      function DBDelete(record: Recordable) {
        deleteDbConnect(record.id).then(() => {
          handleSuccess();
        });
      }

      function handleSuccess() {
        fetch().then();
      }

      /**
       * 构建数据库下面的表列表
       * @param key
       */
      async function buildTableTree(key: string) {
        const result: PageResult<TableInfo> = await getTableList({
          connectId: key,
          pageNum: 1,
          pageSize: 10000
        });
        if (!result) {
          return [];
        }
        const asyncTreeAction: TreeActionType | null = unref(asyncTreeRef);
        result.list.forEach((db) => {
          db["title"] = db.tableName + (db.tableComment ? "[" + db.tableComment + "]" : "");
          db["key"] = key + "," + db.tableName;
          db["icon"] = "ant-design:table-outlined";
          db["iconColor"] = color;
          db["isLeaf"] = true;
        });
        asyncTreeAction?.updateNodeByKey(key, { children: result.list });
        return result.list;
      }

      onMounted(() => {
        fetch();
      });
      return {
        hasPermission,
        registerModal,
        DBCreate,
        handleSuccess,
        treeData,
        handleSelect,
        setSelect,
        asyncTreeRef,
        getTables,
        selectedKeys,
        buildTableTree,
        handleSearch,
        getRightMenuList
      };
    }
  };
</script>

<style scoped></style>